home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / POLYSELF.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  22KB  |  830 lines

  1. /*    SCCS Id: @(#)polyself.c 3.0    89/11/21
  2. /* Polymorph self routine.  Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. #ifdef POLYSELF
  8. #ifdef OVLB
  9. static void NDECL(break_armor);
  10. static void FDECL(drop_weapon,(int));
  11. static void NDECL(skinback);
  12. static void NDECL(uunstick);
  13. static boolean sticky;
  14. #endif /* OVLB */
  15. #endif
  16.  
  17. #ifdef OVLB
  18.  
  19. void
  20. newman()
  21. {
  22.     int tmp, tmp2;
  23.     char buf[BUFSZ];
  24.  
  25.     if (!rn2(10)) {
  26.         flags.female = !flags.female;
  27.         max_rank_sz();
  28.         if (pl_character[0] == 'P')
  29.             Strcpy(pl_character+6, flags.female ? "ess" : "");
  30.         if (pl_character[0] == 'C')
  31.             Strcpy(pl_character+5, flags.female ? "woman" : "man");
  32.     }
  33. #ifdef POLYSELF
  34.     if (u.umonnum != -1) {
  35.         u.acurr = u.macurr;    /* restore old attribs */
  36.         u.amax = u.mamax;
  37.     }
  38.     u.usym = S_HUMAN;
  39.     u.umonnum = -1;
  40.     if (u.uundetected) u.uundetected = 0;
  41.     prme();
  42.     u.mtimedone = u.mh = u.mhmax = 0;
  43. #endif
  44.     tmp = u.uhpmax;
  45.     tmp2 = u.ulevel;
  46.     u.ulevel = u.ulevel-2+rn2(5);
  47.     if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1;
  48.     if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
  49.  
  50.     adjabil(tmp2, (int)u.ulevel);
  51.     tmp = u.uhpmax;
  52.  
  53.     /* random experience points for the new experience level */
  54.     u.uexp = rndexp();
  55. #ifndef LINT
  56.     u.uhpmax = (u.uhpmax-10)*(long)u.ulevel/tmp2 + 19 - rn2(19);
  57. #endif
  58. /* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character
  59.    with 16 hp who polymorphed into a 3rd level one would have an average
  60.    of 48 hp.  */
  61. #ifdef LINT
  62.     u.uhp = u.uhp + tmp;
  63. #else
  64.     u.uhp = u.uhp * (long)u.uhpmax/tmp;
  65. #endif
  66. #ifdef SPELLS
  67.     tmp = u.uenmax;
  68. #  ifndef LINT
  69.     u.uenmax = u.uenmax * (long)u.ulevel/tmp2 + 9 - rn2(19);
  70. #  endif
  71.     if (u.uenmax < 0) u.uenmax = 0;
  72. #  ifndef LINT
  73.     u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);
  74. #  endif
  75. #endif
  76.     redist_attr();
  77.     u.uhunger = rn1(500,500);
  78.     Sick = 0;
  79.     Stoned = 0;
  80.     if (u.uhp <= 0 || u.uhpmax <= 0) {
  81. #ifdef POLYSELF
  82.         if(Polymorph_control) {
  83.             if (u.uhp <= 0) u.uhp = 1;
  84.             if (u.uhpmax <= 0) u.uhpmax = 1;
  85.         } else {
  86. #endif
  87.             Your("new form doesn't seem healthy enough to survive.");
  88.             killer_format = KILLED_BY_AN;
  89.             killer="unsuccessful polymorph";
  90.             done(DIED);
  91. #ifdef POLYSELF
  92.         }
  93. #endif
  94.     }
  95. #ifdef POLYSELF
  96.     set_uasmon();
  97. #endif
  98.     You("feel like a new %sman!", flags.female ? "wo" : "");
  99. #ifdef WIZARD
  100.     if(!wizard) {
  101. #endif
  102. newname:    more();
  103.         do {
  104.             pline("What is your new name? ");
  105.             getlin(buf);
  106.         } while (buf[0]=='\033' || buf[0]==0);
  107.         if (!strcmp(plname,buf)) {
  108.             pline("That is the same as your old name!");
  109.             goto newname;
  110.         }
  111.         (void)strncpy(plname, buf, sizeof(plname)-1);
  112. #ifdef VMS
  113.         Sprintf(SAVEF, "[.save]%d%s", getuid(), plname);
  114.         regularize(SAVEF+7);
  115.         Strcat(SAVEF, ";1");
  116. #else
  117. # ifdef MSDOS
  118.         (void)strcpy(SAVEF, SAVEP);
  119.         {
  120.             int i = strlen(SAVEF);
  121.             (void)strncat(SAVEF, plname, 8);
  122.             regularize(SAVEF+i);
  123.         }
  124.         (void)strcat(SAVEF, ".sav");
  125. # else
  126.         Sprintf(SAVEF, "save/%d%s", getuid(), plname);
  127.         regularize(SAVEF+5);        /* avoid . or / in name */
  128. # endif
  129. #endif
  130. #ifdef WIZARD
  131.     }
  132. #endif
  133.     flags.botl = 1;
  134. #ifdef POLYSELF
  135.     skinback();
  136.     find_ac();
  137.     if (sticky) uunstick();
  138. #endif
  139. }
  140.  
  141. #ifdef POLYSELF
  142. void
  143. polyself()
  144. {
  145.     char buf[BUFSZ];
  146.     int mntmp = -1;
  147.     int tries=0;
  148.     boolean draconian = (uarm && uarm->otyp==DRAGON_SCALE_MAIL &&
  149.         uarm->corpsenm >= PM_GRAY_DRAGON &&
  150.         uarm->corpsenm <= PM_YELLOW_DRAGON);
  151.     boolean iswere = (u.ulycn > -1 || is_were(uasmon));
  152.     boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
  153.     /* We have to calculate sticky in multiple places since we might go
  154.      * through any one of them without going through the others.
  155.      */
  156.     sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  157.  
  158.     if(!Polymorph_control && !draconian && !iswere && !isvamp) {
  159.         if (rn2(20) > ACURR(A_CON)) {
  160.         You("shudder for a moment.");
  161.         losehp(rn2(30),"system shock", KILLED_BY_AN);
  162.         return;
  163.         }
  164.     }
  165.  
  166.     if (Polymorph_control) {
  167.         do {
  168.             pline("Become what kind of monster? [type the name] ");
  169.             getlin(buf);
  170.             mntmp = name_to_mon(buf);
  171.             if (mntmp < 0)
  172.                 pline("I've never heard of such monsters.");
  173.             else if (!polyok(&mons[mntmp]))
  174.                 You("cannot polymorph into that.");
  175.             else break;
  176.         } while(++tries < 5);
  177.         if (tries==5) pline(thats_enough_tries);
  178.     } else if (draconian || iswere || isvamp) {
  179.         /* special changes that don't require polyok() */
  180.         if (draconian) {
  181.             mntmp = uarm->corpsenm;
  182.             if (!(mons[mntmp].geno & G_GENOD)) {
  183.                 You("merge with your scaly armor.");
  184.                 uskin = uarm;
  185.                 uarm = (struct obj *)0;
  186.             }
  187.         } else if (iswere) {
  188.             if (is_were(uasmon))
  189.                 mntmp = PM_HUMAN; /* Illegal; force newman() */
  190.             else
  191.                 mntmp = u.ulycn;
  192.         } else {
  193.             if (u.usym == S_VAMPIRE)
  194.                 mntmp = PM_VAMPIRE_BAT;
  195.             else
  196.                 mntmp = PM_VAMPIRE;
  197.         }
  198.         if (polymon(mntmp))
  199.             return;
  200.     }
  201.  
  202.     if (mntmp < 0) {
  203.         tries = 0;
  204.         do {
  205.             mntmp = rn2(PM_ARCHEOLOGIST);
  206.             /* All valid monsters are from 0 to PM_ARCHEOLOGIST-1 */
  207.         } while(!polyok(&mons[mntmp]) && tries++ < 200);
  208.     }
  209.  
  210.     /* The below polyok() fails either if everything is genocided, or if
  211.      * we deliberately chose something illegal to force newman().
  212.      */
  213.     if (!polyok(&mons[mntmp]) || !rn2(5))
  214.         newman();
  215.     else if(!polymon(mntmp)) return;
  216.  
  217.     if (!uarmg) selftouch("No longer petrify-resistant, you");
  218.     if (Inhell && !Fire_resistance) {
  219.         You("burn to a crisp.");
  220.         killer_format = KILLED_BY;
  221.         killer = "losing fire resistance after polymorphing";
  222.         while(1) {
  223.         done(BURNING);
  224.         You("continue burning.");
  225.         }
  226.     }
  227. }
  228.  
  229. int
  230. polymon(mntmp)    /* returns 1 if polymorph successful */
  231.     int    mntmp;
  232. {
  233.     int    tmp;
  234.     sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  235.  
  236.     if (mons[mntmp].geno & G_GENOD) {
  237.         You("feel rather %s-ish.",mons[mntmp].mname);
  238.         return(0);
  239.     }
  240.  
  241.     if (u.umonnum == -1) {
  242.         /* Human to monster; save human stats */
  243.         u.macurr = u.acurr;
  244.         u.mamax = u.amax;
  245.     } else {
  246.         /* Monster to monster; restore human stats, to be
  247.          * immediately changed to provide stats for the new monster
  248.          */
  249.         u.acurr = u.macurr;
  250.         u.amax = u.mamax;
  251.     }
  252.     tmp = u.umonnum;
  253.     u.umonnum = mntmp;
  254.     set_uasmon();
  255.     u.usym = mons[mntmp].mlet;
  256.  
  257.     if (tmp != mntmp)
  258.         You("turn into %s!", an(mons[mntmp].mname));
  259.     else
  260.         You("feel like a new %s!", mons[mntmp].mname);
  261.  
  262.     /* New stats for monster, to last only as long as polymorphed.
  263.      * Currently only strength gets changed.
  264.      */
  265.     if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118;
  266.  
  267.     if (resists_ston(uasmon) && Stoned) { /* parnes@eniac.seas.upenn.edu */
  268.         Stoned = 0;
  269.         You("no longer seem to be petrifying.");
  270.     }
  271.     if (u.usym == S_FUNGUS && Sick) {
  272.         Sick = 0;
  273.         You("no longer feel sick.");
  274.     }
  275.     if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON) u.mhmax = 80;
  276. #ifdef GOLEMS
  277.     else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp);
  278. #endif /* GOLEMS */
  279.     else {
  280.  
  281.         /*
  282.         tmp = adj_lev(&mons[mntmp]);
  283.          * We can't do this, since there's no such thing as an
  284.          * "experience level of you as a monster" for a polymorphed
  285.          * character.
  286.          */
  287.         tmp = mons[mntmp].mlevel;
  288.         if (!tmp) u.mhmax = rnd(4);
  289.         else u.mhmax = d(tmp, 8);
  290.     }
  291.     u.mh = u.mhmax;
  292.     if (uskin && mntmp != uskin->corpsenm)
  293.         skinback();
  294.     break_armor();
  295.     drop_weapon(1);
  296.     if (u.uundetected && !hides_under(uasmon)) u.uundetected = 0;
  297.     else if (hides_under(uasmon) && (OBJ_AT(u.ux, u.uy) ||
  298.             levl[u.ux][u.uy].gmask))
  299.         u.uundetected = 1;
  300.     prme();
  301.     if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0;
  302.     else if (sticky && !sticks(uasmon)) uunstick();
  303.     u.mtimedone = 500 + rn2(500);
  304.     if (u.ulevel < mons[mntmp].mlevel)
  305.     /* Low level characters can't become high level monsters for long */
  306.         u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel;
  307.     flags.botl = 1;
  308.     if (flags.verbose) {
  309.         if (can_breathe(uasmon))
  310.         pline("Use the command #monster to use your breath weapon.");
  311.         if (attacktype(uasmon, AT_SPIT))
  312.         pline("Use the command #monster to spit venom.");
  313.         if (u.usym == S_NYMPH)
  314.         pline("Use the command #monster to remove an iron ball.");
  315.         if (u.usym == S_UMBER)
  316.         pline("Use the command #monster to confuse monsters.");
  317.         if (is_hider(uasmon))
  318.         pline("Use the command #monster to hide.");
  319.         if (is_were(uasmon))
  320.         pline("Use the command #monster to summon help.");
  321.         if (webmaker(uasmon))
  322.         pline("Use the command #monster to spin a web.");
  323.         if (u.usym == S_UNICORN)
  324.         pline("Use the command #monster to use your horn.");
  325.         if (lays_eggs(uasmon) || u.umonnum == PM_QUEEN_BEE)
  326.         pline("Use the command #sit to lay an egg.");
  327.     }
  328.     find_ac();
  329.     return(1);
  330. }
  331.  
  332. static void
  333. break_armor() {
  334.      struct obj *otmp;
  335.  
  336.      if (breakarm(uasmon)) {
  337.     if (otmp = uarm) {
  338.         if (donning(otmp)) cancel_don();
  339.         You("break out of your armor!");
  340.         (void) Armor_gone();
  341.         useup(otmp);
  342.     }
  343.     if (otmp = uarmc) {
  344.         Your("cloak tears apart!");
  345.         (void) Cloak_off();
  346.         useup(otmp);
  347.     }
  348. #ifdef SHIRT
  349.     if (uarmu) {
  350.         Your("shirt rips to shreds!");
  351.         useup(uarmu);
  352.     }
  353. #endif
  354.      } else if (sliparm(uasmon)) {
  355.     if (otmp = uarm) {
  356.         if (donning(otmp)) cancel_don();
  357.         Your("armor falls around you!");
  358.         (void) Armor_gone();
  359.         dropx(otmp);
  360.     }
  361.     if (otmp = uarmc) {
  362.         You("shrink out of your cloak!");
  363.         (void) Cloak_off();
  364.         dropx(otmp);
  365.     }
  366. #ifdef SHIRT
  367.     if (otmp = uarmu) {
  368.         You("become much too small for your shirt!");
  369.         setworn((struct obj *)0, otmp->owornmask & W_ARMU);
  370.         dropx(otmp);
  371.     }
  372. #endif
  373.      }
  374.      if (nohands(uasmon) || verysmall(uasmon)) {
  375.       if (otmp = uarmg) {
  376.            if (donning(otmp)) cancel_don();
  377.            /* Drop weapon along with gloves */
  378.            You("drop your gloves%s!", uwep ? " and weapon" : "");
  379.            drop_weapon(0);
  380.            (void) Gloves_off();
  381.            dropx(otmp);
  382.       }
  383.       if (otmp = uarms) {
  384.            You("can no longer hold your shield!");
  385.            (void) Shield_off();
  386.            dropx(otmp);
  387.       }
  388.       if (otmp = uarmh) {
  389.            if (donning(otmp)) cancel_don();
  390.            Your("helmet falls to the floor!");
  391.            (void) Helmet_off();
  392.            dropx(otmp);
  393.       }
  394.       if (otmp = uarmf) {
  395.            if (donning(otmp)) cancel_don();
  396.            Your("boots %s off your feet!",
  397.             verysmall(uasmon) ? "slide" : "are pushed");
  398.            (void) Boots_off();
  399.            dropx(otmp);
  400.       }
  401.      }
  402. }
  403.  
  404. static void
  405. drop_weapon(alone)
  406. int alone;
  407. {
  408.      struct obj *otmp;
  409.      if (otmp = uwep) {
  410.       /* !alone check below is currently superfluous but in the
  411.        * future it might not be so if there are monsters which cannot
  412.        * wear gloves but can wield weapons
  413.        */
  414.       if (!alone || cantwield(uasmon)) {
  415.            if (alone) You("find you must drop your weapon!");
  416.            uwepgone();
  417.            dropx(otmp);
  418.       }
  419.      }
  420. }
  421.  
  422. void
  423. rehumanize()
  424. {
  425.     sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  426.  
  427.     u.mh = u.mhmax = u.mtimedone = 0;
  428.      u.acurr = u.macurr;        /* restore old strength */
  429.      u.amax = u.mamax;
  430.     u.usym = S_HUMAN;
  431.     u.umonnum = -1;
  432.     skinback();
  433.     set_uasmon();
  434.     You("return to %sn form!", (pl_character[0] == 'E')? "elve" : "huma");
  435.  
  436.     if (u.uhp < 1)    done(DIED);
  437.     if (!Fire_resistance && Inhell) {
  438.         You("burn to a crisp.");
  439.         killer_format = KILLED_BY;
  440.         killer = "losing fire resistance after rehumanization";
  441.         while(1) {
  442.         done(BURNING);
  443.         You("continue burning.");
  444.         }
  445.     }
  446.     if (!uarmg) selftouch("No longer petrify-resistant, you");
  447.     if (sticky) uunstick();
  448.     nomul(0);
  449.     if (u.uundetected) u.uundetected = 0;
  450.     prme();
  451.     flags.botl = 1;
  452.     find_ac();
  453. }
  454.  
  455. int
  456. dobreathe() {
  457.     if(!getdir(1)) return(0);
  458.     if (rn2(4))
  459.         You("produce a loud and noxious belch.");
  460.     else {
  461.         register struct attack *mattk;
  462.         register int i;
  463.  
  464.         for(i = 0; i < NATTK; i++) {
  465.         mattk = &(uasmon->mattk[i]);
  466.         if(mattk->aatyp == AT_BREA) break;
  467.         }
  468.         buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,
  469.         u.ux, u.uy, u.dx, u.dy);
  470.     }
  471.     return(1);
  472. }
  473.  
  474. int
  475. dospit() {
  476.     struct obj *otmp;
  477.  
  478.     if (!getdir(1)) return(0);
  479.     otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, FALSE);
  480.     otmp->spe = 1; /* to indicate it's yours */
  481.     (void) throwit(otmp);
  482.     return(1);
  483. }
  484.  
  485. int
  486. doremove() {
  487.      if (!Punished) {
  488.       You("are not chained to anything!");
  489.       return(0);
  490.      }
  491.      unpunish();
  492.      return(1);
  493. }
  494.  
  495. int
  496. dospinweb() {
  497.     register struct trap *ttmp = t_at(u.ux,u.uy);
  498.  
  499.     if (Levitation) {
  500.         You("must be on the ground to spin a web.");
  501.         return(0);
  502.     }
  503.     if (u.uswallow) {
  504.         You("release web fluid inside %s.", mon_nam(u.ustuck));
  505.         if (is_animal(u.ustuck->data)) {
  506.             expels(u.ustuck, u.ustuck->data, TRUE);
  507.             return(0);
  508.         }
  509.         if (is_whirly(u.ustuck->data)) {
  510.             int i;
  511.  
  512.             for (i = 0; i < NATTK; i++)
  513.                 if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
  514.                     break;
  515.             if (i == NATTK)
  516.                    impossible("Swallower has no engulfing attack?");
  517.             else {
  518.                 char sweep[30];
  519.  
  520.                 sweep[0] = '\0';
  521.                 switch(u.ustuck->data->mattk[i].adtyp) {
  522.                     case AD_FIRE:
  523.                         Strcpy(sweep, "ignites and ");
  524.                         break;
  525.                     case AD_ELEC:
  526.                         Strcpy(sweep, "fries and ");
  527.                         break;
  528.                     case AD_COLD:
  529.                         Strcpy(sweep,
  530.                               "freezes, shatters and ");
  531.                         break;
  532.                 }
  533.                 pline("The web %sis swept away!", sweep);
  534.             }
  535.             return(0);
  536.         }             /* default: a nasty jelly-like creature */ 
  537.         pline("The web dissolves into %s.", mon_nam(u.ustuck));
  538.         return(0);
  539.     }
  540.     if (u.utrap) {
  541.         You("cannot spin webs while stuck in a trap.");
  542.         return(0);
  543.     }
  544.     if (ttmp) switch (ttmp->ttyp) {
  545.         case SPIKED_PIT:
  546.         case PIT: You("spin a web, covering up the pit.");
  547.             deltrap(ttmp);
  548.             if (Invisible) newsym(u.ux, u.uy);
  549.             return(1);
  550.         case WEB: You("make the web thicker.");
  551.             return(1);
  552.         case SQBRD: pline("The squeaky board is muffled.");
  553.             deltrap(ttmp);
  554.             if (Invisible) newsym(u.ux, u.uy);
  555.             return(1);
  556.         case TELEP_TRAP:
  557.         case LEVEL_TELEP:
  558.             Your("webbing vanishes!");
  559.             return(0);
  560.         case TRAPDOOR: if (!is_maze_lev) {
  561.                 You("web over the trap door.");
  562.                 deltrap(ttmp);
  563.                 if (Invisible) newsym(u.ux, u.uy);
  564.                 return 1;
  565.             }
  566.             /* Fall through */
  567.         case MGTRP:
  568.         case POLY_TRAP:
  569.         case DART_TRAP:
  570.         case ARROW_TRAP:
  571. #ifdef SPELLS
  572.         case ANTI_MAGIC:
  573. #endif
  574.         case LANDMINE:
  575.         case SLP_GAS_TRAP:
  576.         case BEAR_TRAP:
  577.         case RUST_TRAP:
  578.             You("have triggered a trap!");
  579.             dotrap(ttmp);
  580.             return(1);
  581.         default:
  582.             impossible("Webbing over trap type %d?", ttmp->ttyp);
  583.             return(0);
  584.     }
  585.     ttmp = maketrap(u.ux, u.uy, WEB);
  586.     ttmp->tseen = 1;
  587.     if (Invisible) newsym(u.ux, u.uy);
  588.     return(1);
  589. }
  590.  
  591. int
  592. dosummon()
  593. {
  594.     You("call upon your brethren for help!");
  595.     if (!were_summon(uasmon,TRUE))
  596.         pline("But none arrive.");
  597.     return(1);
  598. }
  599.  
  600. int
  601. doconfuse()
  602. {
  603.     register struct monst *mtmp;
  604.     int looked = 0;
  605.  
  606.     if (Blind) {
  607.         You("can't see anything to gaze at.");
  608.         return 0;
  609.     }
  610.     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  611.         if (canseemon(mtmp)) {
  612.         looked = 1;
  613.         if (Invis && !perceives(mtmp->data))
  614.             pline("%s seems not to notice your gaze.", Monnam(mtmp));
  615.         else if (mtmp->minvis && !See_invisible)
  616.             You("can't see where to gaze at %s.", Monnam(mtmp));
  617.         else if (mtmp->mimic)
  618.             continue;
  619.         else if (flags.safe_dog && !Confusion && !Hallucination
  620.           && mtmp->mtame) {
  621.             if (mtmp->mnamelth)
  622.             You("avoid gazing at %s.", NAME(mtmp));
  623.             else
  624.             You("avoid gazing at your %s.",
  625.                         mtmp->data->mname);
  626.         } else {
  627.             if (flags.confirm && mtmp->mpeaceful && !Confusion
  628.                             && !Hallucination) {
  629. #ifdef MACOS
  630.             char mac_tbuf[80];
  631.             if(!flags.silent) SysBeep(1);
  632.             Sprintf(mac_tbuf, "Really confuse %s?", mon_nam(mtmp));
  633.             if(UseMacAlertText(128, mac_tbuf) != 1) continue;
  634. #else
  635.             pline("Really confuse %s? ", mon_nam(mtmp));
  636.             (void) fflush(stdout);
  637.             if (yn() != 'y') continue;
  638. #endif
  639.             setmangry(mtmp);
  640.             }
  641.             if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||
  642.                             !mtmp->mcansee)
  643.             continue;
  644.             if (!mtmp->mconf)
  645.             Your("gaze confuses %s!", mon_nam(mtmp));
  646.             else
  647.             pline("%s is getting more and more confused.",
  648.                             Monnam(mtmp));
  649.             mtmp->mconf = 1;
  650.             if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
  651.             You("are frozen by %s's gaze!", mon_nam(mtmp));
  652.             nomul((u.ulevel > 6 || rn2(4)) ? 
  653.                 -d((int)mtmp->m_lev+1,
  654.                     (int)mtmp->data->mattk[0].damd)
  655.                 : -200);
  656.             return 1;
  657.             }
  658. #ifdef MEDUSA
  659.             if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) {
  660.             pline("Gazing at the awake Medusa is not a very good idea.");
  661.             /* as if gazing at a sleeping anything is fruitful... */
  662.             You("turn to stone...");
  663.             done(STONING);
  664.             }
  665. #endif
  666.         }
  667.         }
  668.     }
  669.     if (!looked) You("gaze at no place in particular.");
  670.     return 1;
  671. }
  672.  
  673. int
  674. dohide()
  675. {
  676.     if (u.uundetected || u.usym == S_MIMIC_DEF) {
  677.         You("are already hiding.");
  678.         return(0);
  679.     }
  680.     if (u.usym == S_MIMIC) {
  681.         u.usym = S_MIMIC_DEF;
  682.         prme();
  683.     } else {
  684.         newsym(u.ux,u.uy);
  685.         u.uundetected = 1;
  686.     }
  687.     return(1);
  688. }
  689.  
  690. static void
  691. uunstick()
  692. {
  693.     kludge("%s is no longer in your clutches.", Monnam(u.ustuck));
  694.     u.ustuck = 0;
  695. }
  696.  
  697. static void
  698. skinback()
  699. {
  700.     if (uskin) {
  701.         Your("skin returns to its original form.");
  702.         uarm = uskin;
  703.         uskin = (struct obj *)0;
  704.     }    
  705. }
  706. #endif
  707.  
  708. #endif /* OVLB */
  709. #ifdef OVL1
  710. const char *
  711. body_part(part)
  712. int part;
  713. {
  714.     /* Note: it is assumed these will never be >22 characters long,
  715.      * plus the trailing null, after pluralizing (since sometimes a
  716.      * buffer is made a fixed size and must be able to hold it)
  717.      */
  718.     static const char NEARDATA *humanoid_parts[] = { "arm", "eye", "face", "finger",
  719.         "fingertip", "foot", "hand", "handed", "head", "leg",
  720.                 "light headed", "neck", "spine", "toe" };
  721. #ifdef POLYSELF
  722.     static const char NEARDATA *jelly_parts[] = { "pseudopod", "dark spot", "front",
  723.         "pseudopod extension", "pseudopod extremity",
  724.         "pseudopod root", "grasp", "grasped", "cerebral area",
  725.         "lower pseudopod", "viscous", "middle", "surface",
  726.         "pseudopod extremity" },
  727.     NEARDATA *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip",
  728.         "rear claw", "foreclaw", "clawed", "head", "rear limb",
  729.         "light headed", "neck", "spine", "rear claw tip" },
  730.     NEARDATA *horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip",
  731.         "rear hoof", "foreclaw", "hooved", "head", "rear limb",
  732.         "light headed", "neck", "backbone", "rear hoof tip" },
  733.     NEARDATA *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle",
  734.         "tentacle tip", "lower appendage", "tentacle", "tentacled",
  735.         "body", "lower tentacle", "rotational", "equator", "body",
  736.         "lower tentacle tip" },
  737.     NEARDATA *fungus_parts[] = { "mycelium", "visual area", "front", "hypha",
  738.         "hypha", "root", "strand", "stranded", "cap area",
  739.         "rhizome", "sporulated", "stalk", "root", "rhizome tip" },
  740.     NEARDATA *vortex_parts[] = { "region", "eye", "front", "minor current",
  741.         "minor current", "lower current", "swirl", "swirled",
  742.         "central core", "lower current", "addled", "center",
  743.         "currents", "edge" },
  744.     NEARDATA *snake_parts[] = { "vestigial limb", "eye", "face", "large scale",
  745.         "large scale tip", "rear region", "scale gap", "scale gapped",
  746.         "head", "rear region", "light headed", "neck", "length",
  747.         "rear scale" };
  748.     
  749.     if (humanoid(uasmon) || (u.usym==S_CENTAUR && 
  750.         (part==ARM || part==FINGER || part==FINGERTIP
  751.         || part==HAND || part==HANDED))) return humanoid_parts[part];
  752.     if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part];
  753.     if (u.usym==S_SNAKE || u.usym==S_NAGA || u.usym==S_WORM)
  754.         return snake_parts[part];
  755.     if (u.usym==S_EYE) return sphere_parts[part];
  756.     if (u.usym==S_JELLY || u.usym==S_PUDDING || u.usym==S_BLOB)
  757.         return jelly_parts[part];
  758.     if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part];
  759.     if (u.usym==S_FUNGUS) return fungus_parts[part];
  760.     return animal_parts[part];
  761. #else
  762.     return humanoid_parts[part];
  763. #endif
  764. }
  765.  
  766. #endif /* OVL1 */
  767. #ifdef OVL0
  768.  
  769. int
  770. poly_gender()
  771. {
  772. /* Returns gender of polymorphed player; 0/1=same meaning as flags.female,
  773.  * 2=none.
  774.  * Used in:
  775.  *    - Seduction by succubus/incubus
  776.  *    - Talking to nymphs (sounds.c)
  777.  * Not used in:
  778.  *    - Messages given by nymphs stealing armor (they can't steal from
  779.  *      incubi/succubi/nymphs, and nonhumanoids can't wear armor).
  780.  *    - Amulet of change (must refer to real gender no matter what
  781.  *      polymorphed into).
  782.  *    - Priest/Priestess, Caveman/Cavewoman (ditto)
  783.  *    - Polymorph self (only happens when human)
  784.  *    - Shopkeeper messages (since referred to as "creature" and not "sir"
  785.  *      or "lady" when polymorphed)
  786.  */
  787. #ifdef POLYSELF
  788.     if (uasmon->mflags2 & M2_FEM) return 1;
  789. # ifdef INFERNO
  790.     if (u.umonnum == PM_INCUBUS) return 0;
  791. # endif
  792.     if (!humanoid(uasmon)) return 2;
  793. #endif
  794.     return flags.female;
  795. }
  796.  
  797. #endif /* OVL0 */
  798. #ifdef OVLB
  799.  
  800. #if defined(POLYSELF) && defined(GOLEMS)
  801. void
  802. ugolemeffects(damtype, dam)
  803. int damtype, dam;
  804. {
  805.     int heal = 0;
  806.     /* We won't bother with "slow"/"haste" since players do not
  807.      * have a monster-specific slow/haste so there is no way to
  808.      * restore the old velocity once they are back to human.
  809.      */
  810.     if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM)
  811.         return;
  812.     switch (damtype) {
  813.         case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM)
  814.                 heal = dam / 6; /* Approx 1 per die */
  815.             break;
  816.         case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM)
  817.                 heal = dam;
  818.             break;
  819.     }
  820.     if (heal && (u.mh < u.mhmax)) {
  821.         u.mh += heal;
  822.         if (u.mh > u.mhmax) u.mh = u.mhmax;
  823.         flags.botl = 1;
  824.         pline("Strangely, you feel better than before.");
  825.     }
  826. }
  827. #endif /* POLYSELF && GOLEMS */
  828.  
  829. #endif /* OVLB */
  830.